#ifndef __BMS_CAN_H__
#define __BMS_CAN_H__

#include <stdint.h>
#include "j1939tp.h"
#include "j1939tp_config.h"

#include "task.h"
#include "FreeRTOS.h"
#include "queue.h"

#include "utils.h"

#ifdef __cplusplus
extern "C" {
#endif

/* 充电桩的 CAN总线地址 */
#define CHARGE_CAN_ADDR         0x56
/* 车端BMS CAN总线地址 */
#define BMS_CAN_ADDR            0xf4
/* 国标充电通讯协议版本号 */
#define CHARGE_CAN_VERSION      0x000101

/* 充电机握手报文 */
#define CHARGE_CHM_PGN          0x2600      /* 充电机握手报文PGN */
/* 充电机辨识报文 */
#define CHARGE_CRM_PGN          0x100       /* 充电机辨识报文PGN */
/* 充电机时间同步信息 */
#define CHARGE_CTS_PGN          0x700       /* 充电机时间同步报文PGN */
/* 充电机最大输出功率 */
#define CHARGE_CML_PGN          0x800
/* 充电机输出准备就绪状态 */
#define CHARGE_CRO_PGN          0xA00
/* 充电机充电状态 */
#define CHARGE_CCS_PGN          0x1200
/* 充电桩数据的极值 */
#define CHARGE_CST_PGN          0x1A00
/* 充电桩统计数据 */
#define CHARGE_CSD_PGN          0x1D00
/* 充电桩错误报文 */
#define CHARGE_CEM_PGN          0x1F00

#define BMS_BHM_PGN             0x2700
#define BMS_BRM_PGN             0x200
#define BMS_BCP_PGN             0x600
#define BMS_BRO_PGN             0x900
#define BMS_BCL_PGN             0x1000
#define BMS_BCS_PGN             0x1100
#define BMS_BSM_PGN             0x1300
#define BMS_BMV_PGN             0x1500
#define BMS_BMT_PGN             0x1600
#define BMS_BSP_PGN             0x1700
#define BMS_BST_PGN             0x1900
#define BMS_BSD_PGN             0x1C00
#define BMS_BEM_PGN             0x1E00

/**
 * @brief BMS通讯报文周期 单位:ms
 */
#define CHM_MESSAGE_PER         250
#define CRM_MESSAGE_PER         250
#define CTS_MESSAGE_PER         250
#define CML_MESSAGE_PER         250
#define CRO_MESSAGE_PER         250
#define CCS_MESSAGE_PER         250
#define CST_MESSAGE_PER         250
#define CSD_MESSAGE_PER         250

/**
 * @brief 充电机编号
 */
#define CHARGE_NUMBER           689009

/**
 * @brief 车端的数据队列结构
 */
typedef struct
{
    uint8_t id;    // 标识是从哪里过来的数据
    uint8_t event; // 标识是什么数据
    j1939_msg_info_t j1939_bms;
    struct
    {
        int len;
        uint8_t buf[256];
    } data;
    void *userdata; // 携带的私有数据
} qmsg_t;

/**
 * @brief BMS控制结构
 */
typedef struct
{
    int status;
    int errcode;
    qmsg_t *msg;
    QueueHandle_t app_q;
    timer_t timer[2];
    /* 充电握手状态机结构 */
    struct {
        int status;
    } shake_fsm;

    /* 充电辨识状态机结构 */
    struct {
        int status;
    } iden_fsm;

    /* 充电配置状态机机构 */
    struct {
        int status;
    } config_fsm;
    /* 充电中状态机结构 */
    struct {
        int status;
    } charg_fsm;
    /* 充电结束状态机结构 */
    struct {
        int status;
    } end_fsm;
} bms_t;

#pragma pack(1)
/**
 * @brief 动力蓄电池的充电参数
 */
typedef union
{
    uint8_t buf[13];
    struct
    {
        uint16_t max_one_charge_vol;    /* 单体最高充电电压,分辨率0.01/位 */
        uint16_t max_charge_curr;       /* 最高充电电流 ,分辨率0.1/位 */
        uint16_t total_energy;          /* 标称总能量 分辨率 0.1/位 */
        uint16_t max_charge_vol;        /* 最高允许充电的总电压 */
        uint8_t max_charge_temp;        /* 最高允许充电温度 偏移量 -50 */
        uint16_t vehicle_soc;           /* 当前电池的SOC 分辨率0.1/位 */
        uint16_t batt_vol;              /* 动力电池当前电压 分辨率0.1V/位 */
    } data;
} __attribute__((packed)) bcp_msg_t;

/**
 * @brief BMS握手报文
 */
typedef union
{
    uint8_t buf[8];
    uint16_t data;
} __attribute__((packed)) bhm_msg_t;

/**
 * @brief 电池充电需求报文
 */
typedef union
{
    uint8_t buf[5];
    struct
    {
        uint16_t voltage;
        uint16_t curr;
        uint8_t mode; /* 1：恒压 ，2：恒流 */
    } data;
} __attribute__((packed)) bcl_msg_t;

/**
 * @brief BMS的车辆辨识报文
 */
typedef union
{
    uint8_t buf[50];
    struct
    {
        uint8_t pro_ver[3];         /* 协议版本号 */
        uint8_t batt_type;          /* 电芯类型 */
        uint16_t batt_sr;           /* 蓄电池的额定容量 精度0.1 */
        uint16_t batt_rt_vol;       /* 蓄电池额定总电压 精度0.1 */
        uint8_t batt_name[4];       /* 电池厂商名称 */
        uint8_t batt_num[4];        /* 电池组序号 */
        uint8_t year;               /* 年 */
        uint8_t month;              /* 月 */
        uint8_t day;                /* 日 */
        uint8_t charge_num;         /* 充放电次数 */
        uint8_t batt_pro;           /* 电池组产权说明 */
        uint8_t :8;                 /* 预留 */
        uint8_t vin[17];            /* VIN码 */
        uint8_t bms_ver[8];         /* BMS的软件版本号 */
    } data;
} __attribute__((packed)) brm_msg_t;

/**
 * @brief 电池充电总状态
 */
typedef union
{
    uint8_t buf[9];
    struct
    {
        uint16_t det_vol;     /* 充电电压测量值 精度0.1 */
        uint16_t det_curr;    /* 充电电流测量值 精度0.1 */
        uint16_t max_one_vol; /* 最高单体动力蓄电池电压及其组号 精度0.1 */
        uint8_t soc;          /* 当前荷电状态 */
        uint16_t rema_time;   /* 剩余充电时间 */
    } data;
} __attribute__((packed)) bcs_msg_t;

/**
 * @brief 动力蓄电池状态信息
 */
typedef union
{
    uint8_t buf[7];
    struct
    {
        uint8_t max_one_vol_num; /* 最高单体电压所在编号 */
        uint8_t max_batt_temp;   /* 最高动力蓄电池温度 */
        uint8_t max_temp_num;    /* 最高温度检测点编号 */
        uint8_t min_batt_temp;   /* 最低动力蓄电池温度 */
        uint8_t min_temp_num;    /* 最低温度检测点编号 */
        union
        {
            uint16_t buf[1];
            struct
            {
                uint16_t over_vol : 2;
                uint16_t over_soc : 2;
                uint16_t over_curr : 2;
                uint16_t over_temp : 2;
                uint16_t ins_state : 2;
                uint16_t conn_state : 2;
                uint16_t charge_en : 2;
                uint16_t : 2;
            } data;
        } bit_convert;
    } data;
} __attribute__((packed)) bsm_msg_t;

/**
 * @brief BMS的故障报文
 */
typedef union
{
    uint8_t buf[4];
    struct
    {
        uint8_t end_charge_reason; /*  终止充电的原因 */
        union
        {
            uint16_t end_charge_fault; /* 终止充电的故障 */
            struct
            {
                uint16_t idf_fault : 2;
                uint16_t out_conn_tempfault : 2;
                uint16_t bms_out_temp_fault : 2;
                uint16_t charge_conn_fault : 2;
                uint16_t batt_temp_fault : 2;
                uint16_t high_relay_fault : 2;
                uint16_t det2_fault : 2;
                uint16_t other_fault : 2;
            } fault_bit;
        } fault;
        uint8_t end_charge_error; /* 终止充电的错误 */
    } data;
} __attribute__((packed)) bst_msg_t;

/**
 * @brief  BMS的统计报文
 */
typedef union
{
    uint8_t buf[7];
    struct
    {
        uint8_t end_soc;             /* 终止SOC */
        uint16_t min_one_charge_vol; /* 动力蓄电池单体最低电压 */
        uint16_t max_one_charge_vol; /* 动力蓄电池单体最高电压 */
        uint8_t min_temp;            /* 动力蓄电池最低温度 */
        uint8_t max_temp;            /* 动力蓄电池最高温度 */
    } data;
} __attribute__((packed)) bsd_msg_t;

/**
 * @brief BMS的错误报文
 */
typedef union
{
    uint8_t buf[4];
    struct
    {
        struct
        {
            /* data */
            uint32_t crm00_timeout : 2;
            uint32_t crmAA_timeout : 2;
            uint32_t : 4;
        } byte0;

        struct
        {
            /* data */
            uint32_t cst_timeout : 2;
            uint32_t cro_timeout : 2;
            uint32_t : 4;
        } byte1;

        struct
        {
            /* data */
            uint32_t ccs_timeout : 2;
            uint32_t cst_timeout : 2;
            uint32_t : 4;
        } byte2;

        struct
        {
            /* data */
            uint32_t csd_timeout : 2;
            uint32_t : 6;
        } byte3;
    } data;
} __attribute__((packed)) bem_msg_t;

/**
 * @brief CML报文结构
 */
typedef union
{
    uint8_t buf[8];
    struct
    {
        uint16_t max_vol;  /* 最大输出电压 */
        uint16_t min_vol;  /* 最小输出电压 */
        uint16_t max_curr; /* 最大输出电流 */
        uint16_t min_curr; /* 最小输出电流 */
    } data;
} __attribute__((packed)) cml_msg_t;

/**
 * @brief CCS报文结构
 */
typedef union
{
    uint8_t buf[8];
    struct
    {
        uint16_t out_vol;
        uint16_t out_curr;
        uint16_t sum_time;
        uint16_t charge_en;
    } data;
} __attribute__((packed)) ccs_msg_t;

/**
 * @brief CST报文结构
 */
typedef union
{
    uint8_t buf[4];
    struct
    {
        /* data */
        struct
        {
            uint8_t target : 2; /* 达到充电机设置的目标值 */
            uint8_t people : 2; /* 人工主动终止 */
            uint8_t fault : 2;  /* 故障终止 */
            uint8_t bms : 2;    /* BMS主动终止 */
        } end;

        struct
        {
            uint16_t over_temp_fault : 2;
            uint16_t conn_fault : 2;
            uint16_t in_over_temp_fault : 2;
            uint16_t energy_output_fault : 2;
            uint16_t scram_fault : 2;
            uint16_t other_fault : 2;
            uint16_t : 4;
        } fault;

        struct
        {
            uint8_t un_curr : 2; /* 电流不匹配 */
            uint8_t un_vol : 2;  /* 电压异常 */
            uint8_t : 4;
        } error;
    } data;
} __attribute__((packed)) cst_msg_t;

/**
 * @brief CEM报文结构
 */
typedef union
{
    uint8_t buf[4];
    struct
    {
        struct
        {
            uint32_t brm_timeout : 2;
            uint32_t : 6;
        } byte0;

        struct
        {
            uint32_t bcp_timeout : 2;
            uint32_t bro_timeout : 2;
            uint32_t : 4;
        } byte1;

        struct
        {
            uint32_t bcs_timeout : 2;
            uint32_t bcl_timeout : 2;
            uint32_t bst_timeout : 2;
            uint32_t : 2;
        } byte2;

        struct
        {
            uint32_t bsd_timeout : 2;
            uint32_t : 6;
        } byte3;
    } data;
} __attribute__((packed)) cem_msg_t;

/**
 * @brief CSD报文结构
 */
typedef union
{
    uint8_t buf[8];
    struct
    {
        uint16_t time_sum;      /* 累计充电时间 */
        uint16_t out_kwh;       /* 输出能量 */
        uint32_t charge_num;    /* 充电机编号 */
    };
} __attribute__((packed)) csd_msg_t;

#pragma pack()

int bms_init(void);

int charge_send_chm(void);
int charge_send_crm(int result);
int charge_send_cts(void);
int charge_send_cml(void);
int charge_send_cro(int result);
int charge_send_cst(uint32_t cst);
int charge_send_ccs(uint32_t vol, uint32_t curr, uint32_t time);
int charge_send_cem(void);
int charge_send_csd(void);

#ifdef __cplusplus
}
#endif
#endif                  /* __BMS_CAN_H__ */



